Load Balance using Nginx
  Let's take the example forward by load balancing the Node.js application.
Checkout the commit
$ cd nginx-and-nodejs-on-docker
$ git checkout 2e3a77e
.env File
The container names are changed:

docker-compose.yml
A new service called node_server_2 is created and the initial server is renamed to node_server_1.

web/server.js
This is an optional change. x-powered-by header that defaults to EXPRESS is  disabled, and a new header X-Server is added to find out which container served the request.

Rebuild & Recreate containers
As usual, rebuild using docker-compose build followed by docker-compose up -d. Once the containers are up, you should be able to browse to http://192.168.99.100:81/users & http://192.168.99.100:82/users. Check the headers using Chrome inspect tool. Notice the X-Server header.

Add Nginx for load balancing
Nginx is super light and a great fit for reverse proxy scenarios like this one. If you are unfamiliar with Nginx, you may want to read my book Nginx: From Beginner to Pro. It is extremely simple and straightforward to use it with Docker.
Let's Dive in
Step 1: Change your directory and checkout the commit
$ cd nginx-and-nodejs-on-docker
$ git checkout bd9e91f
OR view the differences online.
Review the following files:
.env file
It now contains the information about NGINX
# Project Information
COMPOSE_PROJECT_NAME=node-nginx-seed
TAG=1.0
# Database Information
DATABASE_VERSION=mongo:3.4.8
DATABASE_CONTAINER_NAME=mongodb
# NodeJS Information
NODE_VERSION=node:6.11.3
NODE_CONTAINER_NAME_1=node_server_1
NODE_CONTAINER_NAME_2=node_server_2
# Nginx Information
NGINX_VERSION=nginx:1.13.3
NGINX_CONTAINER_NAME=nginx
docker-compose.yml file
version: '2'
services:
  database:
    image: ${DATABASE_VERSION}
    networks:
      - backend
    container_name: ${DATABASE_CONTAINER_NAME}
    volumes:
      - mongo-data:/data/db
      - ./docker/scripts:/scripts
      - ./docker/data:/data
  node_server_1:
    environment:
      - NODE=${NODE_CONTAINER_NAME_1}
    container_name: ${NODE_CONTAINER_NAME_1}
    image: ${NODE_VERSION}
    build:
      context: ./web
      dockerfile: node.dockerfile
    networks:
      - backend
    volumes:
      - ./web:/web
    depends_on:
      - database
  node_server_2:
    environment:
      - NODE=${NODE_CONTAINER_NAME_2}
    container_name: ${NODE_CONTAINER_NAME_2}
    image: ${NODE_VERSION}
    build:
      context: ./web
      dockerfile: node.dockerfile
    networks:
      - backend
    volumes:
      - ./web:/web
    depends_on:
      - database
  nginx:
    container_name: ${NGINX_CONTAINER_NAME}
    image: ${NGINX_VERSION}
    build:
      context: ./nginx
      dockerfile: nginx.dockerfile
    networks:
      - backend
    ports:
      - 80:80
    depends_on:
      - node_server_1
      - node_server_2
      - database
networks:
  backend:
    driver: bridge
volumes:
  mongo-data:
Notice the following changes:
portskey has been removed from individualnodeservers. This is to ensure that you can't reach the Node.js application directly. It avoids exposing your application to the end users.depends_onkey is added to imply dependencies between services.docker-compose upstarts services in dependency order.docker-compose upSERVICE_NAME will automatically include SERVICE’s dependencies.
nginxservice sets the context to thenginxdirectory and refers to thenginx.dockerfilefor its image. It is connected to thebackendnetwork so that it is able to talk to the Node.js apps and maps external port80to the internal port80.
nginx.dockerfile file
FROM nginx:1.13.3
MAINTAINER  rahul soni Soni < rahul soni@xxxx.com>
# Copy the Nginx configuration
COPY nginx.conf /etc/nginx/nginx.conf
# Expose website on port
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
To avoid the container being shutdown, you tell Nginx to run as a foreground process and listen to the requests.
Rebuild & Recreate containers
Rebuild again using docker-compose build followed by docker-compose up -d. Once the containers are up, you should be able to browse to http://192.168.99.100/users. Check the headers using Chrome inspect tool. Notice the X-Server header. You should see it switch values between node_server_1 and node_server_2 if you refresh the page.
What next?
Stay tuned for upcoming articles. You may contact us for your software and consultancy requirements.